package com.xagent.engine.hook.enhance.v1;

import com.xagent.core.Properties;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.AdviceAdapter;

public class XagentMethodVisitor extends AdviceAdapter implements Opcodes {
    protected final Label beginLabel = new Label();
    protected final Label endLabel = new Label();
    protected final Label beginCatchBlock = new Label();
    protected final Label endCatchBlock = new Label();
    public final boolean isConstructor;

    protected XagentMethodVisitor(MethodVisitor methodVisitor, int access, String name, String descriptor) {
        super(Properties.COMMON_ASM_VERSION, methodVisitor, access, name, descriptor);
        isConstructor = "<init>V".equals(name);
    }

    /**
     * 判断是否是抛出异常
     */
    public boolean isThrow(int opcode) {
        return opcode == ATHROW;
    }
    /**
     * 根据操作码的不同情况加载不同返回值
     * */
    public void loadReturn(int opcode) {
        // 构造方法没有返回值
        if (isConstructor) {
            pushNull();
            return;
        }

        switch (opcode) {
            case RETURN:
                pushNull();
                break;
            case ARETURN:
                dup();
                break;
            case LRETURN:
            case DRETURN:
                dup2();
                box(Type.getReturnType(methodDesc));
                break;
            default:
                dup();
                box(Type.getReturnType(methodDesc));
                break;
        }

    }

    public void pushNull() {
        push((Type) null);
    }

    public void loadAllArgs(){
        loadArgArray();
        int argIndex = newLocal(Type.getType(Object[].class));
        storeLocal(argIndex, Type.getType(Object[].class));
        loadLocal(argIndex);
    }
}
